﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace EdgeStatz.ESSystems.Objects
{
    #region Definitions
    public class FolderDefinition : GenericFolderDefinition
    {
        string name;
        string tableName;
        string displayExp;
        string valueExp;
        string orderBy = null;

        FolderLevel level;
        ArrayList subFolders = new ArrayList();

        public SubFolderDefinition[] SubFolders
        {
            get{ return (SubFolderDefinition[])subFolders.ToArray(typeof(SubFolderDefinition)); }
            set
            {
                subFolders = new ArrayList();
                foreach (SubFolderDefinition sdef in value)
                {
                    if (sdef == null)
                        throw new NullReferenceException("Sub folder cannot be null");
                    else
                        subFolders.Add(sdef);
                }
            }
        }
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public string TableName
        {
            get { return tableName; }
            set { tableName = value; }
        }
        public FolderLevel Level
        {
            get { return level; }
            set { level = value; }
        }
        public string DisplayExp
        {
            get { return displayExp; }
            set { displayExp = value; }
        }
        public string ValueExp
        {
            get { return valueExp; }
            set { valueExp = value; }
        }
        public string OrderBy
        {
            get { return orderBy; }
            set { orderBy = value; }
        }
        /// <summary>
        /// Adds a level four folder
        /// </summary>
        /// <param name="name"></param>
        /// <param name="tableName"></param>
        public FolderDefinition(string name, string tableName)
        {
            this.name = name;
            this.tableName = tableName;
            this.level = FolderLevel.Four;
        }
        
        public FolderDefinition(string name, string tableName, FolderLevel level, string display, string value)
        {
            this.name = name;
            this.tableName = tableName;
            this.level = level;
            if (!level.Equals(FolderLevel.Four))
            {
                this.displayExp = display;
                this.valueExp = value;
            }
        }

        public void AddSubFolder(SubFolderDefinition value)
        {
            if(value==null)
                throw new Exception("Cannot add null as a subfolder");
            else 
                subFolders.Add(value);
        }
        
        public SubFolderDefinition GetSubfolderByName(string name)
        {
            foreach (SubFolderDefinition sdef in SubFolders)
            {
                if(sdef.Name.ToUpper().Equals(name.ToUpper()))
                    return sdef;
            }
            return null;
        }

        public void ReplaceSubFolderByName(string name, SubFolderDefinition value)
        {
            for (int i = 0; i < SubFolders.Length; i++)
            {
                if (SubFolders[i].Name.ToUpper().Equals(name.ToUpper()))
                {
                    subFolders.Insert(i, value);
                    subFolders.RemoveAt(i + 1);
                }
            }
        }

        public void RemoveSubFolderByName(string name)
        {
            for (int i = 0; i < SubFolders.Length; i++)
            {
                if (SubFolders[i].Name.ToUpper().Equals(name.ToUpper()))
                {
                    subFolders.RemoveAt(i);
                }
            }
        }  
    }

    public class SubFolderDefinition
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        
        private string column;

        public string Column
        {
            get { return column; }
            set { column = value; }
        }
        private string foreignColumn;

        public string ForeignColumn
        {
            get { return foreignColumn; }
            set { foreignColumn = value; }
        }

        private string condition;

        public string Condition
        {
            get { return condition; }
            set { condition = value; }
        }

        public SubFolderDefinition(string name, string column, string foreignColumn, string condition)
        {
            this.name = name;
            this.column = column;
            this.foreignColumn = foreignColumn;
            this.condition = condition;
        }
    }

    public class EnumFolderDefinition : GenericFolderDefinition
    {
        string name;
        string tableName;
        string display;
        string value;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public string TableName
        {
            get { return tableName; }
            set { tableName = value; }
        }
        public string DisplayExp
        {
            get { return display; }
            set { display = value; }
        }
        public string ValueExp
        {
            get { return value; }
            set { this.value = value; }
        }

        public EnumFolderDefinition(string name, string tableName, string display, string value)
        {
            this.name = name;
            this.tableName = tableName;
            this.display = display;
            this.value = value;
        }
    }

    public interface GenericFolderDefinition
    {
        string Name { get; set; }
        string TableName { get; set; }
        string DisplayExp { get; set; }
        string ValueExp { get; set; }
    }

    #endregion

    public enum FolderLevel { One, Two, Three, Four }
    
    #region Data Objects
    public class FolderObj 
    {
        private FolderDefinition definition;
        private string displayString;
        private string key;

        private SubFolderObj[] subfolders;

        public FolderDefinition Definition
        {
            get { return definition; }
        }

        public string FolderName
        {
            get { return definition != null ? definition.Name : null; }
        }

        public string Display
        {
            set { displayString = value; }
            get { return displayString; }
        }

        public string Key
        {
            set { key = value; }
            get { return key; }
        }

        public FolderObj(string display, string key, FolderDefinition folderDef)
        {
            this.displayString = display;
            this.key = key;
            this.definition = folderDef;

            subfolders = new SubFolderObj[folderDef.SubFolders.Length];
            for (int i = 0; i < folderDef.SubFolders.Length; i++)
            {
                subfolders[i] = new SubFolderObj(folderDef.SubFolders[i].Name);
            }
        }

        public void AddSubFolderItem(string subFolderName, FolderObj item)
        {
            for (int i = 0; i < subfolders.Length; i++)
            {
                if (subfolders[i].Name == subFolderName)
                {
                    subfolders[i].AddFolder(item);
                    return;
                }
            }
        }
    }

    public class SubFolderObj
    {
        string name;

        ArrayList folders = new ArrayList();

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public SubFolderObj(string name)
        {
            this.name = name;
        }

        public void AddFolder(FolderObj item)
        {
            folders.Add(item);
        }
    }
    #endregion
}

